# 系统管理操作日志模型 - 与统一日志系统兼容
import enum
from datetime import datetime
from sqlalchemy import Column, Integer, String, Text, DateTime, Enum
from backend.infrastructure.database import db
from backend.services.unified_log_service import UnifiedLogAction

class SystemLogAction(enum.Enum):
    CREATE = "CREATE"
    UPDATE = "UPDATE"
    DELETE = "DELETE"
    RESTORE = "RESTORE"
    LOGIN = "LOGIN"
    LOGOUT = "LOGOUT"
    OTHER = "OTHER"

class SystemLog(db.Model):
    __tablename__ = 'system_logs'
    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, nullable=True, comment='操作人ID')
    action = Column(Enum(SystemLogAction), nullable=False, comment='操作类型')
    target_id = Column(Integer, nullable=True, comment='目标对象ID')
    detail = Column(Text, comment='操作详情')
    # 变更前后内容，JSON格式，便于追溯
    old_content = Column(Text, comment='修改前的数据(JSON)')
    new_content = Column(Text, comment='修改后的数据(JSON)')
    ip_address = Column(String(50), comment='操作IP')
    operation_time = Column(DateTime, default=datetime.now, comment='操作时间')
    created_at = Column(DateTime, default=datetime.now, comment='日志创建时间')

    def to_dict(self):
        return {
            'id': self.id,
            'user_id': self.user_id,
            'action': self.action.value if self.action else None,
            'target_id': self.target_id,
            'detail': self.detail,
            'old_content': self.old_content,
            'new_content': self.new_content,
            'ip_address': self.ip_address,
            'operation_time': self.operation_time.isoformat() if self.operation_time else None,
            'created_at': self.created_at.isoformat() if self.created_at else None
        }

    # 与统一日志系统兼容的方法
    @classmethod
    def log_create(cls, record, operator='系统', ip_address=None):
        """记录创建操作"""
        from backend.models.user import User
        try:
            # 获取操作人ID
            user_id = None
            if operator != '系统':
                user = User.query.filter_by(username=operator).first()
                if user:
                    user_id = user.id
            
            log = cls(
                user_id=user_id,
                action=SystemLogAction.CREATE,
                target_id=record.id if hasattr(record, 'id') else None,
                detail=f"创建{cls._get_record_type(record)}: {cls._get_record_name(record)}",
                new_content=cls._serialize_content(record),
                ip_address=ip_address,
                operation_time=datetime.now()
            )
            return log
        except Exception as e:
            print(f"记录创建日志失败: {e}")
            return None

    @classmethod
    def log_update(cls, record, old_data, operator='系统', ip_address=None):
        """记录更新操作"""
        from backend.models.user import User
        try:
            # 获取操作人ID
            user_id = None
            if operator != '系统':
                user = User.query.filter_by(username=operator).first()
                if user:
                    user_id = user.id
            
            log = cls(
                user_id=user_id,
                action=SystemLogAction.UPDATE,
                target_id=record.id if hasattr(record, 'id') else None,
                detail=f"编辑{cls._get_record_type(record)}: {cls._get_record_name(record)}",
                old_content=cls._serialize_content(old_data),
                new_content=cls._serialize_content(record),
                ip_address=ip_address,
                operation_time=datetime.now()
            )
            return log
        except Exception as e:
            print(f"记录更新日志失败: {e}")
            return None

    @classmethod
    def log_delete(cls, record, operator='系统', ip_address=None):
        """记录删除操作"""
        from backend.models.user import User
        try:
            # 获取操作人ID
            user_id = None
            if operator != '系统':
                user = User.query.filter_by(username=operator).first()
                if user:
                    user_id = user.id
            
            log = cls(
                user_id=user_id,
                action=SystemLogAction.DELETE,
                target_id=record.id if hasattr(record, 'id') else None,
                detail=f"删除{cls._get_record_type(record)}: {cls._get_record_name(record)}",
                old_content=cls._serialize_content(record),
                ip_address=ip_address,
                operation_time=datetime.now()
            )
            return log
        except Exception as e:
            print(f"记录删除日志失败: {e}")
            return None

    @classmethod
    def log_restore(cls, record_id, student_id=None, old_data=None, restored_data=None, operator='系统', ip_address=None):
        """记录恢复操作"""
        from backend.models.user import User
        try:
            # 获取操作人ID
            user_id = None
            if operator != '系统':
                user = User.query.filter_by(username=operator).first()
                if user:
                    user_id = user.id
            
            log = cls(
                user_id=user_id,
                action=SystemLogAction.RESTORE,  # 恢复操作记录为RESTORE
                target_id=record_id,
                detail=f"恢复系统记录: ID {record_id}",
                old_content=cls._serialize_content(old_data) if old_data else None,
                new_content=cls._serialize_content(restored_data) if restored_data else None,
                ip_address=ip_address,
                operation_time=datetime.now()
            )
            return log
        except Exception as e:
            print(f"记录恢复日志失败: {e}")
            return None

    @classmethod
    def log_login(cls, user, ip_address=None, user_agent=None):
        """记录登录操作"""
        from backend.models.user import User
        try:
            # 获取操作人ID
            user_id = user.id if user else None
            
            # 构建详细信息
            detail = f"用户登录成功"
            if user_agent:
                detail += f" - 设备: {user_agent}"
            
            log = cls(
                user_id=user_id,
                action=SystemLogAction.LOGIN,
                target_id=user_id,
                detail=detail,
                new_content=cls._serialize_content(user),
                ip_address=ip_address,
                operation_time=datetime.now()
            )
            return log
        except Exception as e:
            print(f"记录登录日志失败: {e}")
            return None

    @classmethod
    def log_logout(cls, user, ip_address=None):
        """记录登出操作"""
        from backend.models.user import User
        try:
            # 获取操作人ID
            user_id = user.id if user else None
            
            log = cls(
                user_id=user_id,
                action=SystemLogAction.LOGOUT,
                target_id=user_id,
                detail="用户登出",
                old_content=cls._serialize_content(user),
                ip_address=ip_address,
                operation_time=datetime.now()
            )
            return log
        except Exception as e:
            print(f"记录登出日志失败: {e}")
            return None

    @staticmethod
    def _get_record_type(record):
        """获取记录类型名称"""
        if hasattr(record, '__tablename__'):
            table_name = record.__tablename__
            if 'user' in table_name:
                return '用户'
            elif 'role' in table_name:
                return '角色'
            elif 'permission' in table_name:
                return '权限'
        return '记录'

    @staticmethod
    def _get_record_name(record):
        """获取记录名称"""
        if hasattr(record, 'username'):
            return record.username
        elif hasattr(record, 'name'):
            return record.name
        elif hasattr(record, 'code'):
            return record.code
        else:
            return f"ID {getattr(record, 'id', '未知')}"

    @staticmethod
    def _serialize_content(content):
        """序列化内容为JSON字符串"""
        import json
        try:
            if hasattr(content, 'to_dict'):
                return json.dumps(content.to_dict(), ensure_ascii=False, default=str)
            elif isinstance(content, dict):
                return json.dumps(content, ensure_ascii=False, default=str)
            else:
                return str(content)
        except Exception as e:
            print(f"序列化内容失败: {e}")
            return str(content)
